/*
 *  pthreads.c
 *  
 *
 * Operating Systems Concepts Essentials
 *	Thread Libraries, 4.3.1 PThreads pg.153
 *	Figure 4.9: Multithreaded C Program using PThreads API
 *
 */

#include <pthread.h> 
#include <stdio.h> 
#include <stdlib.h>
#include <unistd.h>
#include <semaphore.h>

#include "buffer.h"

#define TRUE 1
#define SLEEP_MAX 3

void *producer(void *param); /* producer thread */
void *consumer(void *param); /* consumer thread */

int main(int argc, char *argv[])
{
/*
	if (argc < 3) { 
		fprintf(stderr,"usage: a.out <integer value>\n"); 
		return -1;
	}
	
	if (atoi(argv[0]) < 0 || atoi(argv[1]) < 0 || atoi(argv[2]) < 0) {
		fprintf(stderr,"%d must be >= 0\n",atoi(argv[0]), atoi(argv[1]), atoi(argv[2]) ); 
		return -1;
	}
	
*/	
	
	printf("Start Program 1\n"); 

	/* initialize random seed: */
	srand ( time(NULL) );

	int i = 0;
	int sleepTime = 15, producers = 1, consumers = 1;
	/*	
	 sleepTime = atoi(argv[0]);
	 producers = atoi(argv[1]);
	 consumers = atoi(argv[2]);
	 */	
	
	pthread_t t_producer, t_consumer; /* the thread identifier */ 
	pthread_attr_t attr_producer, attr_consumer; /* set of thread attributes */

	printf("Start Program 2\n"); 

		
	/* create the mutex lock */ 
	pthread_mutex_init(&mutex,NULL);
	
	/* create the semaphore */ 
	sem_init(&empty, 0, BUFFER_SIZE);
	sem_init(&full, 0, BUFFER_SIZE);
	
	printf("Start Program 3\n"); 

	
	/* get the default attributes */ 
	pthread_attr_init(&attr_producer); 
	pthread_attr_init(&attr_consumer); 
	
	printf("Start Program 4\n"); 

	/* create the thread */ 
	pthread_create(&t_producer,&attr_producer,producer,argv[1]); /* producer thread */
	pthread_create(&t_consumer,&attr_consumer,consumer,argv[1]); /* consumer thread */
	
	printf("Start Program 5\n"); 

	/* wait for the threads to exit */
	pthread_join(t_producer,NULL);
	pthread_join(t_consumer,NULL);

	printf("Sleeping.. 8\n"); 

	sleep(sleepTime);
	
	
	printf("Exit Sleep 9\n"); 

	/* 1. Get command line arguments argv[1],argv[2],argv[3] */
	/* 2. Initialize buffer */ 
	/* 3. Create producer thread(s) */ 
	/* 4. Create consumer thread(s) */ 
	/* 5. Sleep */ 
	/* 6. Exit */
	

	return 0;
	
}

void *producer(void *param) { 
	buffer_item item;

	/* initialize random seed: */
	srand ( 1 ) ;

	while (TRUE) { 
		
		/* sleep for a random period of time */ 
		//Sleeps for random period less than SLEEP_MAX
		sleep(rand()%SLEEP_MAX); 
		
		printf("Producing.. 6\n"); 

		/* generate a random number */ 
		item = rand() %100 ; 
		if (insert_item(item))
			printf("report error condition PRODUCER"); 
		else
			printf("producer produced %d\n",item); 
	}
}	

void *consumer(void *param) {
	buffer_item item;
	
	/* initialize random seed: */
	srand ( 1 );
	
	while (TRUE) { 
		/* sleep for a random period of time */ 
		//Sleeps for random period less than SLEEP_MAX
		sleep( rand() % SLEEP_MAX ); 
		
		printf("Consuming.. 7\n"); 

		if (remove_item(&item))
			printf("report error condition CONSUMER"); 
		else
			printf("consumer consumed %d\n",item);
	}
}


